//package com.fm.webrtc.websocket;
//
//import android.os.Build;
//import android.util.Log;
//
//import androidx.annotation.RequiresApi;
//
//import com.fm.sdptransform.SdpTransform;
//import com.fm.sdptransform.mediasoup.json.Rtcp;
//import com.fm.sdptransform.message.SdpMessage;
//import com.fm.sdptransform.sdp.Candidate;
//import com.fm.sdptransform.sdp.Ext;
//import com.fm.sdptransform.sdp.Fingerprint;
//import com.fm.sdptransform.sdp.Groups;
//import com.fm.sdptransform.sdp.Media;
//import com.fm.sdptransform.sdp.MsidSemantic;
//import com.fm.sdptransform.sdp.Origin;
//import com.fm.sdptransform.sdp.RtcpFb;
//import com.fm.sdptransform.sdp.Rtp;
//import com.fm.sdptransform.sdp.Ssrcs;
//import com.fm.sdptransform.sdp.Timing;
//import com.fm.sdptransform.callback.CallbackSdp;
//import com.fm.webrtc.connection.MediasoupPeerConnection;
//import com.fm.sdptransform.mediasoup.json.HeaderExtension;
//import com.fm.sdptransform.mediasoup.json.RtcpFeedback;
//import com.fm.sdptransform.mediasoup.json.Rtx;
//import com.fm.sdptransform.mediasoup.json.Codec;
//import com.fm.sdptransform.mediasoup.json.Encoding;
//import com.fm.sdptransform.mediasoup.json.RtpParameters;
//import com.fm.webrtc.websocket.message.Message;
//import com.fm.webrtc.websocket.message.MessageType;
//import com.fm.webrtc.websocket.message.MessageUtil;
//import com.fm.webrtc.websocket.message.transport.DtlsParameters;
//import com.fm.webrtc.websocket.message.transport.Fingerprints;
//import com.fm.webrtc.websocket.message.request.ConnectWebrtcTransport;
//import com.fm.webrtc.websocket.message.request.CreateTransport;
//import com.fm.webrtc.websocket.message.request.Join;
//import com.fm.webrtc.websocket.message.request.Produce;
//import com.fm.sdptransform.Sdp;
//import com.fm.webrtc.websocket.message.response.ConnectWebrtcTransportResponse;
//import com.fm.webrtc.websocket.message.response.CreateTransportResponse;
//import com.fm.webrtc.websocket.message.response.JoinResponse;
//import com.fm.webrtc.websocket.message.response.MemberDestroyResponse;
//import com.fm.webrtc.websocket.message.response.NewConsumeResponse;
//import com.fm.webrtc.websocket.message.transport.IceCandidates;
//import com.google.gson.Gson;
//import com.google.gson.JsonObject;
//import com.google.gson.reflect.TypeToken;
//
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//
//import okhttp3.OkHttpClient;
//import okhttp3.Request;
//import okhttp3.Response;
//import okhttp3.WebSocket;
//import okhttp3.WebSocketListener;
//
//@RequiresApi(api = Build.VERSION_CODES.O)
//public class WebSocketUtil implements CallbackSdp {
//    private final static String TAG = "websocket";
//    private WebSocket webSocket;
//    private OkHttpClient okHttpClient;
//    private String roomId = "fm";
//    private String peerId = "";
//    private Request request;
//
//
//    private Sdp sdp;
//    private Sdp answerSdp;
//    private Sdp localAnswerSdp;
//    private CreateTransportResponse sendCreateTransportResponse;
//    private CreateTransportResponse recvCreateTransportResponse;
//    private JoinResponse joinResponse;
//    private ConnectWebrtcTransportResponse connectWebrtcTransportResponse;
//    private NewConsumeResponse newConsumeResponse;
//    private MemberDestroyResponse memberDestroy;
//    private String sendTransportId = "";
//    private String recvTransportId = "";
//    private boolean isOpen = false;
//    HashMap<String, RtpParameters> rtpParametersList = new HashMap<>();
//    MediasoupPeerConnection sendMediasoupPeerConnection;
//    MediasoupPeerConnection recvMediasoupPeerConnection;
//
//    public void send(){
//        this.sendMediasoupPeerConnection.initPeerConnection();
//       // this.sendMediasoupPeerConnection.addVideoTrack();
//        this.sendMediasoupPeerConnection.addAudioTrack();
//      //  this.sendMediasoupPeerConnection.startVideoCapturer();
//        this.sendMediasoupPeerConnection.createOffer(this);
//    }
//
//    public void recv(){
//        this.recvMediasoupPeerConnection.initPeerConnection();
//    }
//
//    public void createAnswer(){
//        recvMediasoupPeerConnection.createAnswer(this);
//    }
//
//
//
//    public void open(MediasoupPeerConnection sendMediasoupPeerConnection, MediasoupPeerConnection recvMediasoupPeerConnection) {
//
//        this.sendMediasoupPeerConnection = sendMediasoupPeerConnection;
//        this.recvMediasoupPeerConnection = recvMediasoupPeerConnection;
//      //  send();
//        recv();
//       // this.mediasoupPeerConnection.createAnswer(this);
//        this.okHttpClient = new OkHttpClient();
//
//
//        this.request = new Request.Builder()
////                .url("wss://www.duxingzhe.top:4443/roomId/" + roomId)
//                .url("ws://192.168.0.131:8888/roomId/" + roomId)
//
//                .build();
//
//        this.webSocket = this.okHttpClient.newWebSocket(request, new WebSocketListener() {
//            @Override
//            public void onOpen(WebSocket webSocket, Response response) {
//                // WebSocket 连接成功打开时的回调
//                Log.e(TAG, response.toString());
//                isOpen = true;
//                join();
//            }
//
//            @Override
//            public void onMessage(WebSocket webSocket, String text) {
//                // 收到 WebSocket 文本消息时的回调
//                Log.e(TAG, text);
//                Message<JsonObject> message = MessageUtil.decoder(text, new TypeToken<Message<JsonObject>>() {
//                }.getType());
//                JsonObject data = message.getData();
//                if (message.getType().equals(MessageType.join)) {
//                    joinResponse(data);
//                  //  createTransport(false);
//                    createTransport(true);
//                }
//                if (message.getType().equals(MessageType.createTransport)) {
//                    CreateTransportResponse createTransportResponse = createTransportResponse(data);
//                    if (!createTransportResponse.consume) {
//                        connectWebrtcTransport(false, sendTransportId);
//                    }
//                }
//                if (message.getType().equals(MessageType.connectWebRtcTransport)) {
//                    connectWebrtcTransportResponse(data);
//                    if (!connectWebrtcTransportResponse.consume){
//                        produce();
//                    }
//                }
//                if (message.getType().equals(MessageType.newConsume)) {
//                    newConsumeResponse(data);
//                    newConsumeResponse.rtpParameters.kind = newConsumeResponse.kind;
//                    rtpParametersList.put(newConsumeResponse.id, newConsumeResponse.rtpParameters);
//                    Fingerprint fingerprint = new Fingerprint();
//                    fingerprint.hash = recvCreateTransportResponse.dtlsParameters.fingerprints[0].value;
//                    fingerprint.type = recvCreateTransportResponse.dtlsParameters.fingerprints[0].algorithm;
//
////                    Sdp consumeSdp = Sdp.recv(rtpParametersList,
////                            fingerprint,
////                            recvCreateTransportResponse.iceParameters.usernameFragment,
////                            recvCreateTransportResponse.iceParameters.password,
////                            createCandidate(recvCreateTransportResponse)
////                            );
////                    String offer = SdpTransform.write(MessageUtil.toJson(consumeSdp));
////                    recvMediasoupPeerConnection.setLocalDescription(offer);
////                    createAnswer();
////                    Log.e("newConsume", newConsumeResponse.toString());
//                }
//
//                if (message.getType().equals(MessageType.memberDestroy)) {
//                    memberDestroy(data);
//                    for (String consumeId :memberDestroy.consume) {
//                        RtpParameters rtpParameters = rtpParametersList.get(consumeId);
//                        if (rtpParameters != null)
//                             recvMediasoupPeerConnection.getCallbackMediaStream().removeStream(rtpParameters.rtcp.cname);
//                    }
//
//                }
//            }
//
//            @Override
//            public void onClosing(WebSocket webSocket, int code, String reason) {
//                // WebSocket 正在关闭时的回调
//            }
//
//            @Override
//            public void onClosed(WebSocket webSocket, int code, String reason) {
//                // WebSocket 关闭后的回调
//            }
//
//            @Override
//            public void onFailure(WebSocket webSocket, Throwable t, Response response) {
//                // WebSocket 连接失败时的回调
//                t.printStackTrace();
//            }
//        });
//        webSocket.request();
//    }
//
//    // 处理返回数据
//    public void joinResponse(JsonObject data) {
//        joinResponse = MessageUtil.jsonToObject(data, JoinResponse.class);
//        roomId = joinResponse.getRoomId();
//        peerId = joinResponse.getPeerId();
//
//        Log.e(TAG, joinResponse.toString());
//    }
//
//
//    public Candidate[] createCandidate(CreateTransportResponse createTransportResponse) {
//        Candidate[] candidates = new Candidate[createTransportResponse.iceCandidates.length];
//        int index = 0;
//        for (IceCandidates iceCandidates : createTransportResponse.iceCandidates) {
//            Candidate candidate = new Candidate();
//            candidate.ip = iceCandidates.ip;
//            candidate.port = iceCandidates.port;
//            candidate.foundation = iceCandidates.foundation;
//            candidate.transport = iceCandidates.protocol;
//            candidate.priority = iceCandidates.priority;
//            candidate.type = iceCandidates.type;
//            candidate.component = 1;
//            candidates[index++] = candidate;
//        }
//        return candidates;
//    }
//
//    @RequiresApi(api = Build.VERSION_CODES.O)
//    public void createAnswerSdp() {
//        this.answerSdp = new Sdp();
//        this.answerSdp.name = "-";
//        MsidSemantic msidSemantic = new MsidSemantic();
//        msidSemantic.semantic = "WMS";
//        msidSemantic.token = "*";
//        this.answerSdp.icelite = "ice-lite";
//        this.answerSdp.msidSemantic = msidSemantic;
//        Origin origin = new Origin();
//        origin.address = "127.0.0.1";
//        origin.ipVer = 4;
//        origin.netType = "IN";
//        origin.sessionId = "10000";
//        origin.username = "fm";
//        origin.sessionVersion = this.sdp.media.length;
//        this.answerSdp.origin = origin;
//
//        Fingerprint fingerprint = new Fingerprint();
//        fingerprint.hash = this.sendCreateTransportResponse.dtlsParameters.fingerprints[0].value;
//        fingerprint.type = this.sendCreateTransportResponse.dtlsParameters.fingerprints[0].algorithm;
//
//        IceCandidates iceCandidates = this.sendCreateTransportResponse.iceCandidates[0];
//        this.answerSdp.timing = new Timing();
//        this.answerSdp.timing.start = 0;
//        this.answerSdp.timing.stop = 0;
//        this.answerSdp.media = Media.filterMedia(
//                this.sdp.media,
//                fingerprint,
//                this.sendCreateTransportResponse.iceParameters.usernameFragment,
//                this.sendCreateTransportResponse.iceParameters.password,
//                createCandidate(sendCreateTransportResponse),
//                joinResponse.rtpCapabilities.headerExtensions
//        );
//        Log.e("fuweicong", Arrays.toString(this.sdp.media));
//        Log.e("fuweicong", MessageUtil.toJson(this.sdp));
//        Groups[] groups = new Groups[1];
//        Groups groups1 = new Groups();
//        String[] midsArray = new String[this.answerSdp.media.length];
//        int index = 0;
//        for (Media media: this.answerSdp.media) {
//            midsArray[index++] = media.mid;
//        }
//        groups1.mids = String.join(" ", midsArray);
//        groups1.type = "BUNDLE";
//        groups[0] = groups1;
//        this.answerSdp.groups = groups;
//
//        sendMediasoupPeerConnection.setRemoteDescription(SdpTransform.write(MessageUtil.toJson(this.answerSdp)));
//    }
//
//    @RequiresApi(api = Build.VERSION_CODES.O)
//    public CreateTransportResponse createTransportResponse(JsonObject data) {
//        CreateTransportResponse createTransportResponse = MessageUtil.jsonToObject(data, CreateTransportResponse.class);
//        if (createTransportResponse.consume) {
//            this.recvCreateTransportResponse = createTransportResponse;
//            this.recvTransportId = recvCreateTransportResponse.id;
//        } else {
//            this.sendCreateTransportResponse = createTransportResponse;
//            this.sendTransportId = sendCreateTransportResponse.id;
//
//            createAnswerSdp();
//        }
//
//
//        Log.e(TAG, createTransportResponse.toString());
//        return createTransportResponse;
//    }
//
//    public void connectWebrtcTransportResponse(JsonObject data){
//        this.connectWebrtcTransportResponse = MessageUtil.jsonToObject(data, ConnectWebrtcTransportResponse.class);
//    }
//
//    public void newConsumeResponse(JsonObject data){
//        this.newConsumeResponse = MessageUtil.jsonToObject(data, NewConsumeResponse.class);
//    }
//
//    public void memberDestroy(JsonObject data){
//        this.memberDestroy = MessageUtil.jsonToObject(data, MemberDestroyResponse.class);
//    }
//
//
//    //发送数据
//    public void join() {
//        Join join = new Join();
//        join.setRoomId(this.roomId);
//        join.setPeerId(this.peerId);
//        this.webSocket.send(MessageUtil.encoder(MessageType.join, join));
//    }
//
//    public void createTransport(boolean consume) {
//        CreateTransport createTransport = new CreateTransport();
//        createTransport.consume = consume;
//        createTransport.setPeerId(this.peerId);
//        createTransport.setRoomId(this.roomId);
//        this.webSocket.send(MessageUtil.encoder(MessageType.createTransport, createTransport));
//    }
//
//    public void connectWebrtcTransport(boolean consume, String transportId) {
//        ConnectWebrtcTransport connectWebrtcTransport = new ConnectWebrtcTransport();
//        connectWebrtcTransport.setPeerId(this.peerId);
//        connectWebrtcTransport.setRoomId(this.roomId);
//        connectWebrtcTransport.consume = consume;
//        connectWebrtcTransport.transportId = transportId;
//        DtlsParameters dtlsParameters = new DtlsParameters();
//        dtlsParameters.role = "client";
//
//        Fingerprints[] fingerprintArray = new Fingerprints[1];
//        for (int i = 0; i < 1; i++) {
//            Fingerprints fingerprints = new Fingerprints();
//            if (consume) {
//                fingerprints.algorithm = localAnswerSdp.media[i].fingerprint.type;
//                fingerprints.value = localAnswerSdp.media[i].fingerprint.hash;
//            } else {
//                fingerprints.algorithm = sdp.media[i].fingerprint.type;
//                fingerprints.value = sdp.media[i].fingerprint.hash;
//            }
//
//            fingerprintArray[i] = fingerprints;
//        }
//
//        dtlsParameters.fingerprints = fingerprintArray;
//        connectWebrtcTransport.dtlsParameters = dtlsParameters;
//        Log.e("connect", MessageUtil.encoder(MessageType.connectWebRtcTransport, connectWebrtcTransport));
//        this.webSocket.send(MessageUtil.encoder(MessageType.connectWebRtcTransport, connectWebrtcTransport));
//    }
//
//    private RtcpFeedback[] rtcpFeedbacks(RtcpFb[] rtcpFbs, int payLoadType) {
//        int count = 0;
//        for (RtcpFb rtcpFb : rtcpFbs) {
//            if (payLoadType == Integer.valueOf(rtcpFb.payload)) {
//                count++;
//            }
//        }
//        RtcpFeedback[] rtcpFeedbacks = new RtcpFeedback[count];
//        int index = 0;
//        for (RtcpFb rtcpFb : rtcpFbs) {
//            if (payLoadType == Integer.valueOf(rtcpFb.payload)) {
//                RtcpFeedback rtcpFeedback = new RtcpFeedback();
//                rtcpFeedback.type = rtcpFb.type;
//                rtcpFeedback.parameter = rtcpFb.subtype;
//                rtcpFeedbacks[index++] = rtcpFeedback;
//            }
//        }
//        return rtcpFeedbacks;
//    }
//
//    private Codec[] setProduceCodec(Rtp[] rtps, RtcpFb[] rtcpFbs, String kind) {
//        Codec[] codecs = new Codec[1]; //需要跟服务器作比对
//        for (int i = 0; i < 1; i++) {
//            Codec codec = new Codec();
//            codec.clockRate = rtps[i].rate;
//            codec.mimeType = kind+ "/" + rtps[i].codec;
//            if(rtps[i].encoding != null)
//                codec.channels = Integer.valueOf(rtps[i].encoding);
//            codec.payloadType = rtps[i].payload;
//            codec.rtcpFeedback = rtcpFeedbacks(rtcpFbs, codec.payloadType);
//            codecs[i] = codec;
//        }
//        return codecs;
//    }
//
//    private HeaderExtension[] headerExtensions(Ext[] exts) {
//        HeaderExtension[] headerExtensions = new HeaderExtension[exts.length];
//        int index = 0;
//        for (Ext ext : exts) {
//            HeaderExtension headerExtension = new HeaderExtension();
//            headerExtension.uri = ext.uri;
//            headerExtension.encrypt = false;
//            headerExtension.id = ext.value;
//            headerExtensions[index++] = headerExtension;
//        }
//        return headerExtensions;
//    }
//
//    public Encoding[] encodings(Ssrcs[] ssrcArray) {
//        List<Encoding> encodingList = new ArrayList<>();
//        List<Long> ssrcList = new ArrayList<>();
//        Encoding encoding = new Encoding();
//
//        for (Ssrcs ssrcs : ssrcArray) {
//            if (!ssrcList.contains(ssrcs.id) && ssrcList.size() > 0) {
//                Rtx rtx = new Rtx();
//                rtx.ssrc = ssrcs.id;
//                encoding.rtx = rtx;
//            }
//
//            if (ssrcList.size() == 0) {
//                encoding.dtx = false;
//                encoding.ssrc = ssrcs.id;
//            }
//
//            ssrcList.add(ssrcs.id);
//        }
//        encodingList.add(encoding);
//
//        Encoding[] encodings = new Encoding[encodingList.size()];
//        encodingList.toArray(encodings);
//
//        return encodings;
//    }
//
//    public Rtcp getRtcpCname(Ssrcs[] ssrcArray){
//        Rtcp rtcp = new Rtcp();
//        for (Ssrcs ssrcs: ssrcArray) {
//            if (ssrcs.attribute.equals("cname")) {
//                rtcp.cname = ssrcs.value;
//                rtcp.reducedSize = true;
//            }
//        }
//        return rtcp;
//    }
//
//    public void produce() {
//
//        int length = this.answerSdp.media.length;
//        for (int i = 0; i < length; i++) {
//            Media media = this.sdp.media[i];
//            Log.e("media", media.toString());
//            Produce produce = new Produce();
//            produce.setRoomId(roomId);
//            produce.setPeerId(peerId);
//            produce.transportId = this.sendTransportId;
//            produce.kind = media.type;
//            RtpParameters rtpParameters = new RtpParameters();
//
//            Rtp[] rtps = media.rtp;
//            rtpParameters.codecs = setProduceCodec(rtps, this.answerSdp.media[i].rtcpFb, media.type);
//            rtpParameters.headerExtensions = headerExtensions(this.answerSdp.media[i].ext);
//            rtpParameters.encodings = encodings(media.ssrcs);
//            rtpParameters.rtcp = getRtcpCname(media.ssrcs);
//            produce.rtpParameters = rtpParameters;
//            Log.e("produce", produce.toString());
//            this.webSocket.send(MessageUtil.encoder(MessageType.produce, produce));
//        }
//
//    }
//
//    @Override
//    public void offer(SdpMessage sdpMessage) {
//        String jsonSdp = SdpTransform.parse(sdpMessage.getSdp());
//        Gson gson = new Gson();
//        Log.e("offer", sdpMessage.getSdp());
//        this.sdp = gson.fromJson(jsonSdp, Sdp.class);
//        Log.e("webrtcjsonsdp", jsonSdp);
//      //  this.sdp = gson.fromJson(jsonSdp, Sdp.class);
////        Media[] medias = sdp.media;
////        for (Media media : medias) {
////            Log.e("fuweicong", media.fingerprint.toString());
////            Log.e("fuweicong", media.iceUfrag);
////            Log.e("fuweicong", media.icePwd);
////        }
//    }
//
//    @Override
//    public void answer(SdpMessage sdpMessage) {
//        Log.e("answer", sdpMessage.toString());
//        String jsonSdp = SdpTransform.parse(sdpMessage.getSdp());
//        Gson gson = new Gson();
//        Log.e("fuweicong", jsonSdp);
//        this.localAnswerSdp = gson.fromJson(jsonSdp, Sdp.class);
//        connectWebrtcTransport(true, recvTransportId);
//    }
//}
